package gamehistory.player;

import java.util.HashMap;

import scg.gen.AccountAcceptTrans;
import scg.gen.AccountSolveTrans;
import scg.gen.PlayerTrans;

import gamehistory.utils.xml.XMLModel;

/**
 * 
 * @author Brent Kersanske
 *
 */
public class PlayerModel extends XMLModel {
	
	private static final String PLAYER 		  = "player";
	private static final String ROUND_HISTORY = "roundHistory";
	private static final String ID	   		  = "id";
	private static final String NAME   		  = "name";

	private Integer playerID;
	private String playerName;
	private HashMap<Integer, PlayerRoundModel> rounds;
	
	private Double accountValueTracker;
	
	public PlayerModel(Integer playerID, String playerName) {
		super(PLAYER);
		this.playerID   		 = playerID;
		this.playerName 		 = playerName;
		this.rounds				 = new HashMap<Integer, PlayerRoundModel>();
		this.rounds.put(0, PlayerRoundModel.getStartingRound());
		this.accountValueTracker = 100.0d;
	}	
	
	/**
	 * Gets the ID of this player model.
	 * @return
	 */
	public Integer getPlayerID() {
		return playerID;
	}

	/**
	 * Gets the player name of this player model.
	 * @return
	 */
	public String getPlayerName() {
		return playerName;
	}
	
	/**
	 * 
	 * @param roundNumber
	 * @param transactions
	 */
	public void assimilatePlayerTransactions(int roundNumber, PlayerTrans transactions) {
		ensureRoundHistoryAvailability(roundNumber);
		PlayerRoundModel roundHistory = rounds.get(roundNumber);
		roundHistory.updateNumberOfAccepts(transactions.getAcceptTrans().length());
		roundHistory.updateNumberOfOffers(transactions.getOfferTrans().length());
		roundHistory.updateNumberOfProvides(transactions.getProvidedTrans().length());
		roundHistory.updateNumberOfReoffers(transactions.getReofferTrans().length());
		roundHistory.updateNumberOfSolves(transactions.getSolvedTrans().length());
		rounds.put(roundNumber, roundHistory);		
	}
	
	/**
	 * 
	 * @param roundNumber
	 * @param accountAcceptTransaction
	 */
	public void assimilateAccountAcceptTransactionForAcceptor(int roundNumber, AccountAcceptTrans accountAcceptTransaction) {
		ensureRoundHistoryAvailability(roundNumber);
		PlayerRoundModel roundHistory = rounds.get(roundNumber);
		accountValueTracker = accountValueTracker - accountAcceptTransaction.getAmount();
		roundHistory.updateAccountValue(accountValueTracker.doubleValue());
		rounds.put(roundNumber, roundHistory);
	}
	
	/**
	 * 
	 * @param roundNumber
	 * @param accountAcceptTransaction
	 */
	public void assimilateAccountAcceptTransactionForOfferer(int roundNumber, AccountAcceptTrans accountAcceptTransaction) {
		ensureRoundHistoryAvailability(roundNumber);
		PlayerRoundModel roundHistory = rounds.get(roundNumber);
		accountValueTracker = accountValueTracker + accountAcceptTransaction.getAmount();
		roundHistory.updateAccountValue(accountValueTracker.doubleValue());	
		rounds.put(roundNumber, roundHistory);
	}
	
	/**
	 * 
	 * @param roundNumber
	 * @param accountSolveTransaction
	 */
	public void assimilateAccountSolveTransactionForSolver(int roundNumber, AccountSolveTrans accountSolveTransaction) {
		ensureRoundHistoryAvailability(roundNumber);
		PlayerRoundModel roundHistory = rounds.get(roundNumber);
		accountValueTracker = accountValueTracker + accountSolveTransaction.getAmount();
		roundHistory.updateAccountValue(accountValueTracker.doubleValue());
		rounds.put(roundNumber, roundHistory);
	}
	
	/**
	 * 
	 * @param roundNumber
	 * @param accountSolveTransaction
	 */
	public void assimilateAccountSolveTransactionForOfferer(int roundNumber, AccountSolveTrans accountSolveTransaction) {
		ensureRoundHistoryAvailability(roundNumber);
		PlayerRoundModel roundHistory = rounds.get(roundNumber);
		accountValueTracker = accountValueTracker - accountSolveTransaction.getAmount();
		roundHistory.updateAccountValue(accountValueTracker.doubleValue());
		rounds.put(roundNumber, roundHistory);
	}
	
	/**
	 * 
	 * @param roundNumber
	 */
	private void ensureRoundHistoryAvailability(int roundNumber) {
		if(!rounds.containsKey(roundNumber)) {
			PlayerRoundModel round = new PlayerRoundModel(roundNumber, accountValueTracker);
			rounds.put(roundNumber, round);
		}	
	}	
	
	/**
	 * 
	 */
	@Override
	public void buildModel() {
		addAttribute(ID,   String.valueOf(this.playerID));
		addAttribute(NAME, this.playerName);
		XMLModel roundHistoryModel = new XMLModel(ROUND_HISTORY);
		for(PlayerRoundModel round : this.rounds.values()) {
			round.buildModel();
			roundHistoryModel.addChildModel(round);
		}
		addChildModel(roundHistoryModel);		
	}
}
